package com.ctos.ojbackendjudgeservice.judge.startegy;

import cn.hutool.json.JSONUtil;

import com.ctos.ojbackendjudgeservice.judge.JudgeResult;
import com.ctos.ojbackendmodel.dto.question.JudgeCase;
import com.ctos.ojbackendmodel.dto.question.JudgeConfig;
import com.ctos.ojbackendmodel.dto.questionsubmit.JudgeInfo;
import com.ctos.ojbackendmodel.entity.Question;
import com.ctos.ojbackendmodel.enums.JudgeInfoMessageEnum;
import com.ctos.ojbackendmodel.enums.QuestionSubmitStatusEnum;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 默认策略
 */
@Slf4j
public class JavaLanguageJudgeStrategy implements JudgeStrategy {
    @Override
    public JudgeResult doJudge(JudgeContext judgeContext) {
        JudgeInfo judgeInfo = judgeContext.getJudgeInfo();
        List<String> outputList = judgeContext.getOutputList();
        Question question = judgeContext.getQuestion();
        List<JudgeCase> judgeCaseList = judgeContext.getJudgeCaseList();
        List<String> needOutputList = judgeCaseList.stream().map(JudgeCase::getOutput).collect(Collectors.toList());
        JudgeResult judgeResult = new JudgeResult();


        JudgeInfoMessageEnum judgeInfoMessageEnum =  JudgeInfoMessageEnum.WAITING;

        
        if (outputList == null || outputList.size() != needOutputList.size()){
            judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;
            judgeInfo.setMessage(judgeInfoMessageEnum.getValue());
            judgeResult.setJudgeInfo(judgeInfo);
            judgeResult.setStatus(QuestionSubmitStatusEnum.FAILED.getValue());
            return judgeResult;
        }

        for (int i = 0; i < outputList.size(); i++) {
            if (!needOutputList.get(i).equals(outputList.get(i))){
                judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;
                judgeInfo.setMessage(judgeInfoMessageEnum.getValue());
                judgeResult.setJudgeInfo(judgeInfo);
                judgeResult.setStatus(QuestionSubmitStatusEnum.FAILED.getValue());
                return judgeResult;
            }
        }


        Long JudgeTime = judgeInfo.getTime();
        Long JudgeMemory = judgeInfo.getMemory();

        String judgeConfigStr = question.getJudgeConfig();
        JudgeConfig judgeConfig = JSONUtil.toBean(judgeConfigStr, JudgeConfig.class);
        Long memoryLimit = judgeConfig.getMemoryLimit();
        Long timeLimit = judgeConfig.getTimeLimit();
        if (memoryLimit < JudgeMemory-1024*1024*8){
            judgeInfoMessageEnum = JudgeInfoMessageEnum.MEMORY_LIMIT_EXCEEDED;
            judgeInfo.setMessage(judgeInfoMessageEnum.getValue());
            judgeResult.setJudgeInfo(judgeInfo);
            judgeResult.setStatus(QuestionSubmitStatusEnum.FAILED.getValue());
            return judgeResult;
        }

        if(timeLimit < (JudgeTime -10000L)){
            judgeInfoMessageEnum = JudgeInfoMessageEnum.TIME_LIMIT_EXCEEDED;
            judgeInfo.setMessage(judgeInfoMessageEnum.getValue());
            judgeResult.setJudgeInfo(judgeInfo);
            judgeResult.setStatus(QuestionSubmitStatusEnum.FAILED.getValue());
            return judgeResult;
        }

        judgeInfoMessageEnum = JudgeInfoMessageEnum.ACCEPT;
        judgeInfo.setMessage(judgeInfoMessageEnum.getValue());
        judgeResult.setJudgeInfo(judgeInfo);
        judgeResult.setStatus(QuestionSubmitStatusEnum.SUCCEED.getValue());
        return judgeResult;
    }
}
